﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Ccr.Adapters.WinForms;
using Microsoft.Ccr.Adapters.Wpf;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using System.Runtime.InteropServices;
using System.Xml;

namespace LabyRob
{
	/// <summary>
	/// Interaction logic for UserControl1.xaml
	/// </summary>
	public partial class Dashboard : Window
	{
		/// <summary>
		/// WinAPI function to find a window
		/// </summary>
		/// <param name="lpClassName">Class name</param>
		/// <param name="lpWindowName">Window name</param>
		/// <returns></returns>
		[DllImport("user32.dll")]
		public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

		/// <summary>
		/// WinAPI function to hide/show a window
		/// </summary>
		/// <param name="hWnd">Window handle</param>
		/// <param name="nCmdShow">Show/Hide command</param>
		/// <returns></returns>
		[DllImport("user32.dll")]
		static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

		#region Properties
		private LabyRobService _service;
		private int _logItemsCount = 0;
		private bool isWheelTogether = true;
		#endregion

		/// <summary>
		/// Creates a new instance of the user interface
		/// </summary>
		public Dashboard(LabyRobService service)
		{
			InitializeComponent();
			_service = service;
			HideConsole();
		}

		/// <summary>
		/// Hides console window
		/// </summary>
		public void HideConsole() {
			// Finds the console window:
			IntPtr hWnd = FindWindow(null, "C:\\Users\\" + System.Environment.GetEnvironmentVariable("USERNAME")  + "\\Microsoft Robotics Dev Studio 2008 R2\\bin\\dsshost.exe");
			//ShowWindow(hWnd, 0);
		}

		#region Interface methods
		/// <summary>
		/// Add log item into the console
		/// </summary>
		/// <param name="entry">Log entry</param>
		public void addLogItem(LogEntry entry)
		{
			// Create new row:
			RowDefinition row = new RowDefinition();
			row.Height = GridLength.Auto;
			console.RowDefinitions.Add(row);
			// Add icon:
			Image image = new Image();
			image.Source = new BitmapImage(new Uri("D:\\Documents\\Studijos\\III-as kursas\\II-as semestras\\Programu sistemu analizes ir projektavimo irankiai\\Kursinis. Lego MindStorms robotas\\LabyRob\\Images\\" + entry.type.Name.ToLower() + ".png"));
			image.VerticalAlignment = VerticalAlignment.Top;
			image.Margin = new Thickness(0, 5, 0, 0);
			image.Height = 16;
			image.Width = 16;
			Grid.SetColumn(image, 0);
			Grid.SetRow(image, _logItemsCount);
			console.Children.Add(image);
			// Add date:
			Label date = new Label();
			date.Content = entry.time.ToString("hh:mm:ss").Trim() + ": ";
			Grid.SetColumn(date, 1);
			Grid.SetRow(date, _logItemsCount);
			console.Children.Add(date);
			// Add text:
			Label text = new Label();
			text.Content = entry.subject;
			Grid.SetColumn(text, 2);
			Grid.SetRow(text, _logItemsCount);
			console.Children.Add(text);
			console.Height = console.ActualHeight;
			consoleScrollBar.ScrollToBottom();
			// Increase line counter:
			_logItemsCount++;
		}
		#endregion

		#region Event Handlers
		/// <summary>
		/// Keyboard keys events handler
		/// </summary>
		/// <param name="sender">Object</param>
		/// <param name="e">Event</param>
		private void window_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.Key == Key.Up)
			{
				MoveForward.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="color"></param>
		public void alert(String color)
		{
			//MessageBox.Show(color);
			clr.Content = color;
		}

		/// <summary>
		/// Closes the application completely
		/// </summary>
		/// <param name="sender">Object</param>
		/// <param name="e">Event</param>
		private void window_Closed(object sender, EventArgs e)
		{
			_service.Exit();
			Environment.Exit(0);
		}

		/// <summary>
		/// On left wheels slider
		/// </summary>
		/// <param name="sender">Object</param>
		/// <param name="e">Event</param>
		private void LeftWheelSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (LeftWheelSlider != null && RightWheelSlider != null && _service != null)
			{
				if (isWheelTogether)
					RightWheelSlider.Value = LeftWheelSlider.Value;
				_service.SetWheelsPower(LeftWheelSlider.Value / 10, RightWheelSlider.Value / 10);
			}
		}

		/// <summary>
		/// On right wheel slider
		/// </summary>
		/// <param name="sender">Object</param>
		/// <param name="e">Event</param>
		private void RightWheelSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (LeftWheelSlider != null && RightWheelSlider != null && _service != null)
			{
				if (isWheelTogether)
					LeftWheelSlider.Value = RightWheelSlider.Value;
				//_service.SetWheelsPower(LeftWheelSlider.Value / 10, RightWheelSlider.Value / 10);
			}
		}

		/// <summary>
		/// On wheels together check
		/// </summary>
		/// <param name="sender">Object</param>
		/// <param name="e">Event</param>
		private void WheelsTogether_Checked(object sender, RoutedEventArgs e)
		{
			isWheelTogether = true;
			RightWheelSlider.Value = LeftWheelSlider.Value;
		}

		/// <summary>
		/// On wheels together uncheck
		/// </summary>
		/// <param name="sender">Object</param>
		/// <param name="e">Event</param>
		private void WheelsTogether_Unchecked(object sender, RoutedEventArgs e)
		{
			isWheelTogether = false;
		}
		#endregion

		private void MoveForward_Click(object sender, RoutedEventArgs e)
		{
			addLogItem(new LogEntry("Driving forward", new XmlQualifiedName("info"), DateTime.Now));
			_service.DoDrive(LeftWheelSlider.Value / 10, RightWheelSlider.Value / 10);
		}

		private void MoveBackward_Click(object sender, RoutedEventArgs e)
		{
			addLogItem(new LogEntry("Driving backward", new XmlQualifiedName("info"), DateTime.Now));
			_service.DoDrive(LeftWheelSlider.Value / -10, RightWheelSlider.Value / -10);
		}

		private void MoveLeft_Click(object sender, RoutedEventArgs e)
		{
			addLogItem(new LogEntry("Turning left", new XmlQualifiedName("info"), DateTime.Now));
			_service.DoDrive(LeftWheelSlider.Value / -10, RightWheelSlider.Value / 10);
		}

		private void MoveRight_Click(object sender, RoutedEventArgs e)
		{
			addLogItem(new LogEntry("Turning right", new XmlQualifiedName("info"), DateTime.Now));
			_service.DoDrive(LeftWheelSlider.Value / 10, RightWheelSlider.Value / -10);
		}
	}
}